package Lib3d.PresetModel3d;


import Lib3d.Vector3d;
import Lib3d.MyUtils.Debug;
import Lib3d.SceneGraph.Impl.ObjectNodeImpl;
import main.JavaRenderer;

import java.awt.Color;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;

/**
 * A sphere 3d model implementation.
 * 
 * @author Wassim Chegham
 * @version 0.1
 * @category Lib3d.PresetModel3d
 * 
 */
public class Sphere extends ObjectNodeImpl {

    public static final int GLU_LINE = 0;

    public static final int GLU_FILL = 1;
    private Vector3d color;

    private float radius;
    // Material
    float no_mat[] = {
            10.0f, 0.0f, 0.0f, 1.0f
    };

    float mat_ambient[] = {
            0.7f, 0.7f, 0.7f, 1.0f
    };
    float mat_ambient_color[] = {
            0.8f, 0.8f, 0.2f, 1.0f
    };
    float mat_diffuse[] = {
            0.1f, 0.5f, 0.8f, 1.0f
    };
    float mat_specular[] = {
            1.0f, 1.0f, 1.0f, 1.0f
    };
    float no_shininess[] = {
        0.0f
    };
    float low_shininess[] = {
        15.0f
    };
    float high_shininess[] = {
        100.0f
    };
    float mat_emission[] = {
            0.3f, 0.2f, 0.2f, 0.0f
    };
    private final int s;
    private final int f;

    private final Vector3d sphereCenter;

    public Sphere() {
        this(new Vector3d(0, 0, 0), 100, Color.BLACK, 30, 30);
    }

    public Sphere(final Color color) {
        this(new Vector3d(0, 0, 0), 100, color, 30, 30);
    }

    public Sphere(final Vector3d sphereCenter, final float radius) {
        this(sphereCenter, radius, Color.BLACK, 30, 30);
    }

    public Sphere(final Vector3d sphereCenter, final float radius, final Color color,
            final int s, final int f) {
        super();
        this.sphereCenter = sphereCenter;
        this.radius = radius;
        this.s = s;
        this.f = f;
        this.setSphereColor(color);
    }

    @Override
    public void draw(final GLAutoDrawable gLDrawable) {
        super.draw(gLDrawable);
        final GL gl = gLDrawable.getGL();

        gl.glPushMatrix();

        gl.glTranslatef(this.sphereCenter.get(0), this.sphereCenter.get(1),
                this.sphereCenter.get(2));

        gl.glEnable(GL.GL_COLOR_MATERIAL);

        gl.glColor3fv(this.color.toBuffer());

        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, this.mat_ambient, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, this.mat_diffuse, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, this.mat_specular, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, this.high_shininess, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_EMISSION, this.mat_emission, 0);

        final GLU glu = JavaRenderer.glu;
        final GLUquadric earth = glu.gluNewQuadric();

        if (Debug.gluDrawStyle == Sphere.GLU_LINE) {
            glu.gluQuadricDrawStyle(earth, GLU.GLU_LINE);
        }
        else if (Debug.gluDrawStyle == Sphere.GLU_FILL) {
            glu.gluQuadricDrawStyle(earth, GLU.GLU_FILL);
        }

        glu.gluQuadricNormals(earth, GLU.GLU_SMOOTH);
        glu.gluQuadricOrientation(earth, GLU.GLU_OUTSIDE);
        glu.gluSphere(earth, this.radius, this.s, this.f);
        glu.gluDeleteQuadric(earth);

        gl.glDisable(GL.GL_COLOR_MATERIAL);
        gl.glPopMatrix();

    }

    public float getRadius() {
        return this.radius;
    }

    public Vector3d getSphereCenter() {
        return this.sphereCenter;
    }

    public void setRadius(final float radius) {
        this.radius = radius;
    }

    public void setSphereColor(final Color color) {
        this.color = new Vector3d(color.getRed(), color.getGreen(), color.getBlue());
    }

    private Vector3d color2vec(final Color color) {
        return new Vector3d(color.getRed(), color.getGreen(), color.getBlue());
    }

}
